package com.sites.cds.common.directive;

import java.util.ArrayList;
import java.util.List;

import com.jfinal.aop.Aop;
import com.jfinal.template.Directive;
import com.jfinal.template.Env;
import com.jfinal.template.TemplateException;
import com.jfinal.template.expr.ast.Expr;
import com.jfinal.template.expr.ast.ExprList;
import com.jfinal.template.io.Writer;
import com.jfinal.template.stat.ParseException;
import com.jfinal.template.stat.Scope;
import com.sites.common.model.Article;

/**
 * 最新资讯指令：获取指定栏目的最新文章
 * 
 * 使用方法一：栏目标识(暂时只支持栏目英文名获取数据)
 * #news(enNames, listSize, paraName)
 * 		<li><a href="#(paraName.getArticleUrl())">#(paraName.title)</a></li>
 * #end
 * 
 * @author zyg
 * 2020年2月16日 下午5:02:47
 */
public class LatestNewsDirective extends Directive {

	private Expr colEnNamesExpr;//指令的第一个参数：栏目enNames
	private Expr listSizeExpr;//指令的第二个参数：文章列表数
	private Expr paraNameExpr;//指令的第三个参数：放置数据的参数名，可选
	private String colEnNames;//栏目enNames
	private List<String> colEnNameList = new ArrayList<String>();
	private int listSize;//需要显示的文章数
	private String paraName = "a";//放置数据的参数名，有默认值
	private int paraNums;//指令参数个数
	
	private DirectiveService srv = Aop.get(DirectiveService.class);
	
	@Override
	public void setExprList(ExprList exprList) {
		paraNums = exprList.length();
		//指令参数个数校验
		if(paraNums<2 || paraNums>3){
			throw new ParseException("Wrong number parameter of #news directive, two or three parameters allowed", location);
		}
		colEnNamesExpr = exprList.getExpr(0);
		listSizeExpr = exprList.getExpr(1);
		if(paraNums==3){
			paraNameExpr = exprList.getExpr(2);
		}
	}
	
	@Override
	public void exec(Env env, Scope scope, Writer writer) {
		Object colEnNamesObject = colEnNamesExpr.eval(scope);
		if(colEnNamesObject instanceof String){
			colEnNames = (String) colEnNamesObject;
			colEnNameList = formatIds(colEnNames);
		} else {
			throw new TemplateException("The first parameter of #news directive must be String type", location);
		}
		
		Object listSizeObject = listSizeExpr.eval(scope);
		if(listSizeObject instanceof Integer){
			listSize = (Integer) listSizeObject;
		} else {
			throw new TemplateException("The second parameter of #news directive must be Integer type", location);
		}
		
		if(paraNums==3){
			Object paraNameObject = paraNameExpr.eval(scope);
			if(paraNameObject instanceof String){
				paraName = (String)paraNameObject;
			} else {
				throw new TemplateException("The third parameter of #news directive must be String type", location);
			}
		}
		
		//数据库查询文章列表，使用缓存
		List<Article> articles = srv.getArtListByColEnNames(colEnNameList, listSize);
		for(Article article : articles){
			scope.set(paraName, article);
			stat.exec(env, scope, writer);
		}

	}
	
	@Override
	public boolean hasEnd() {
		return true;
	}

	private List<String> formatIds(String colEnNames){
		try {
			List<String> cols = new ArrayList<String>();
			if(colEnNames.contains(",")){
				String[] temps = colEnNames.split(",");
				for(int i=0,j=temps.length; i<j; i++){
					cols.add(temps[i]);
				}
			} else {
				cols.add(colEnNames);
			}
			return cols;
		} catch (Exception e) {
			e.printStackTrace();
			throw new TemplateException("The first parameter of #news was wrong", location);
		}
	}
}
